package org.kepler.chat.api.infra.security.auth;

import com.fasterxml.jackson.databind.ObjectMapper;
import org.bigdata.frame.util.ReturnDatas;
import org.kepler.chat.api.infra.util.ErrorCode;
import org.kepler.chat.api.infra.security.exceptions.InvalidJwtTokenException;
import org.kepler.chat.api.infra.security.exceptions.JwtBadCredentialsException;
import org.kepler.chat.api.infra.security.exceptions.JwtExpiredTokenException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.stereotype.Component;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * 
 * @author ake
 *
 * Aug 3, 2016
 */
@Component
public class RestAwareAuthenticationFailureHandler implements AuthenticationFailureHandler {
    private final ObjectMapper mapper;
    
    @Autowired
    public RestAwareAuthenticationFailureHandler(ObjectMapper mapper) {
        this.mapper = mapper;
    }	
    
	@Override
	public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response,
			AuthenticationException e) throws IOException, ServletException {
		
		response.setContentType(MediaType.APPLICATION_JSON_VALUE);
		response.setCharacterEncoding("UTF-8");

		ReturnDatas returnDatas = ReturnDatas.getErrorReturnDatas();

		if (e instanceof JwtBadCredentialsException) {
			ErrorCode errorCode = ((JwtBadCredentialsException) e).getErrorCode();
			returnDatas.setStatusCode(""+errorCode.getCode());
			returnDatas.setMessage(errorCode.getMessage());
		} else if (e instanceof InvalidJwtTokenException) {
			returnDatas.setStatusCode(""+ErrorCode.API_TOKEN_EXPIRED.getCode());
			returnDatas.setMessage(ErrorCode.API_TOKEN_EXPIRED.getMessage());
		} else if (e instanceof JwtExpiredTokenException) {
			returnDatas.setStatusCode(""+ErrorCode.API_TOKEN_EXPIRED.getCode());
			returnDatas.setMessage(ErrorCode.API_TOKEN_EXPIRED.getMessage());
		} else if (e instanceof BadCredentialsException) {
			returnDatas.setStatusCode(""+ErrorCode.API_BAD_CREDENTIALS.getCode());
			returnDatas.setMessage(ErrorCode.API_BAD_CREDENTIALS.getMessage());
			returnDatas.setMessage("Invalid username or password");
		} else {
			returnDatas.setStatusCode(""+ErrorCode.API_AUTHENTICATION_FAILED.getCode());
			returnDatas.setMessage(ErrorCode.API_AUTHENTICATION_FAILED.getMessage());
		}

		mapper.writeValue(response.getWriter(), returnDatas);
	}
}
